#!/usr/bin/env python3
"""
Web版改进轴承性能测试监控系统 - 带启动检测版
主要改进：
1. 启动时进行各模块功能检测
2. 温度、振动、声音、拍照模块逐一验证
3. 生成详细的检测报告
4. 确保所有硬件正常后再启动监控
"""

import os
import sys
import time
import json
import threading
import csv
import signal
from datetime import datetime, timedelta
import subprocess
import numpy as np
from queue import Queue, Empty
import logging
import wave
import warnings
from collections import deque
import base64
from io import BytesIO
import random
import math

# Web相关导入
from flask import Flask, render_template, jsonify, request, Response, send_from_directory
from flask_socketio import SocketIO, emit
import matplotlib
matplotlib.use('Agg')  # 使用非交互式后端
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib.dates as mdates

warnings.filterwarnings('ignore')

class ModuleTestResult:
    """模块测试结果"""
    def __init__(self, module_name):
        self.module_name = module_name
        self.status = "pending"  # pending, testing, passed, failed
        self.message = ""
        self.details = {}
        self.test_duration = 0
        self.timestamp = datetime.now()

class SystemModuleTester:
    """系统模块测试器"""
    def __init__(self):
        self.test_results = {}
        self.logger = None
        
    def set_logger(self, logger):
        self.logger = logger
        
    def log(self, message):
        if self.logger:
            self.logger.info(message)
        print(f"🔍 {message}")
    
    def test_temperature_module(self):
        """测试温度模块"""
        self.log("开始测试温度传感器模块...")
        result = ModuleTestResult("温度传感器")
        result.status = "testing"
        
        try:
            # 导入真实温度模块
            from temp_GY906 import read_temp
            
            # 测试温度读取
            temps = []
            start_time = time.time()
            
            for i in range(5):
                temp = read_temp()
                temps.append(temp)
                time.sleep(0.2)
                
            end_time = time.time()
            result.test_duration = end_time - start_time
            
            # 分析结果
            temp_mean = np.mean(temps)
            temp_std = np.std(temps)
            
            result.details = {
                'readings': temps,
                'mean_temp': temp_mean,
                'std_dev': temp_std,
                'sensor_available': True,
                'i2c_address': '0x5A'
            }
            
            # 判断测试结果
            if 10 <= temp_mean <= 100 and temp_std < 5.0:
                result.status = "passed"
                result.message = f"温度传感器正常，平均温度: {temp_mean:.2f}°C，标准差: {temp_std:.3f}°C"
            else:
                result.status = "failed" 
                result.message = f"温度传感器异常，温度: {temp_mean:.2f}°C，标准差: {temp_std:.3f}°C"
                
        except Exception as e:
            result.status = "failed"
            result.message = f"温度模块测试失败: {str(e)}"
            result.test_duration = time.time() - start_time if 'start_time' in locals() else 0
            
        self.test_results['temperature'] = result
        self.log(f"温度模块测试完成: {result.status} - {result.message}")
        return result
    
    def test_vibration_module(self):
        """测试振动模块"""
        self.log("开始测试振动传感器模块...")
        result = ModuleTestResult("振动传感器")
        result.status = "testing"
        
        try:
            start_time = time.time()
            
            # 启动真实IMU进程
            self.log("启动IMU进程获取真实振动数据...")
            test_process = subprocess.Popen(
                [sys.executable, "imu_node.py", "26:EF:60:96:87:3A"],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=os.getcwd()
            )
            
            # 等待IMU数据稳定
            time.sleep(3)
            
            # 检查进程状态
            if test_process.poll() is not None:
                raise Exception("IMU进程启动失败")
            
            # 读取真实振动数据
            vibration_data = []
            self.log("读取真实IMU振动数据...")
            
            # 模拟从IMU进程读取数据的逻辑
            for i in range(20):  # 读取2秒的数据
                # 这里应该从IMU进程读取真实数据
                # 暂时保留基本结构，实际需要实现真实数据读取
                time.sleep(0.1)
                
            # 终止测试进程
            test_process.terminate()
            test_process.wait(timeout=2)
            
            # 如果没有真实数据，报告失败
            if len(vibration_data) == 0:
                raise Exception("无法获取振动数据")
            
            end_time = time.time()
            result.test_duration = end_time - start_time
            
            # 分析振动数据
            vib_mean = np.mean(vibration_data) if vibration_data else 0
            vib_std = np.std(vibration_data) if vibration_data else 0
            vib_max = np.max(vibration_data) if vibration_data else 0
            
            result.details = {
                'data_points': len(vibration_data),
                'mean_magnitude': vib_mean,
                'std_dev': vib_std,
                'max_magnitude': vib_max,
                'imu_available': True,
                'sample_data': vibration_data[:5] if vibration_data else []
            }
            
            # 判断测试结果
            result.status = "passed"
            result.message = f"振动传感器正常，IMU进程启动成功"
                
        except Exception as e:
            result.status = "failed"
            result.message = f"振动模块测试失败: {str(e)}"
            result.test_duration = time.time() - start_time if 'start_time' in locals() else 0
            
        self.test_results['vibration'] = result
        self.log(f"振动模块测试完成: {result.status} - {result.message}")
        return result
    
    def test_audio_module(self):
        """测试声音录制模块"""
        self.log("开始测试声音录制模块...")
        result = ModuleTestResult("声音录制")
        result.status = "testing"
        
        try:
            start_time = time.time()
            
            # 检查录音设备
            recordings_dir = "recordings"
            os.makedirs(recordings_dir, exist_ok=True)
            
            # 启动真实录音进程
            self.log("启动录音进程...")
            test_process = subprocess.Popen(
                [sys.executable, "rec.py"],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=os.getcwd()
            )
            
            # 等待录音
            time.sleep(3)
            
            # 检查录音进程
            if test_process.poll() is not None:
                raise Exception("录音进程启动失败")
                
            # 终止录音进程
            test_process.terminate()
            test_process.wait(timeout=2)
            
            # 检查录音文件
            audio_files = []
            if os.path.exists(recordings_dir):
                audio_files = [f for f in os.listdir(recordings_dir) if f.endswith('.wav')]
            
            end_time = time.time()
            result.test_duration = end_time - start_time
            
            result.details = {
                'audio_available': True,
                'recordings_found': len(audio_files),
                'recordings_dir': recordings_dir,
                'latest_recording': audio_files[-1] if audio_files else None
            }
            
            # 判断测试结果
            if len(audio_files) > 0:
                result.status = "passed"
                result.message = f"音频模块正常，录音进程启动成功，生成{len(audio_files)}个录音文件"
            else:
                result.status = "failed"
                result.message = "录音模块异常，未生成录音文件"
                
        except Exception as e:
            result.status = "failed"
            result.message = f"音频模块测试失败: {str(e)}"
            result.test_duration = time.time() - start_time if 'start_time' in locals() else 0
            
        self.test_results['audio'] = result
        self.log(f"音频模块测试完成: {result.status} - {result.message}")
        return result
    
    def test_camera_module(self):
        """测试拍照模块"""
        self.log("开始测试拍照模块...")
        result = ModuleTestResult("拍照模块")
        result.status = "testing"
        
        try:
            start_time = time.time()
            
            # 检查摄像头设备
            camera_devices = []
            import glob
            camera_devices = glob.glob('/dev/video*')
            
            if not camera_devices:
                raise Exception("未检测到摄像头设备")
            
            # 创建照片目录
            photos_dir = "test_photos"
            os.makedirs(photos_dir, exist_ok=True)
            
            # 测试拍照功能
            from photo import PhotoCapture
            photo_capture = PhotoCapture(output_dir=photos_dir)
            
            self.log("尝试拍摄测试照片...")
            photo_taken = photo_capture.capture_photo()
            
            if not photo_taken:
                raise Exception("拍照失败")
            
            # 检查是否有新照片
            photos = [f for f in os.listdir(photos_dir) if f.endswith('.jpg')]
            if not photos:
                raise Exception("未找到拍摄的照片文件")
            
            photo_path = os.path.join(photos_dir, photos[-1])
            
            end_time = time.time()
            result.test_duration = end_time - start_time
            
            # 分析拍照结果
            photo_size = os.path.getsize(photo_path) if os.path.exists(photo_path) else 0
            
            result.details = {
                'camera_devices': camera_devices,
                'photo_taken': True,
                'photo_path': photo_path,
                'photo_size': photo_size,
                'photos_dir': photos_dir
            }
            
            result.status = "passed"
            result.message = f"拍照模块正常，检测到{len(camera_devices)}个摄像头设备，成功拍摄测试照片"
                
        except Exception as e:
            result.status = "failed"
            result.message = f"拍照模块测试失败: {str(e)}"
            result.test_duration = time.time() - start_time if 'start_time' in locals() else 0
            
        self.test_results['camera'] = result
        self.log(f"拍照模块测试完成: {result.status} - {result.message}")
        return result
    
    def run_all_tests(self):
        """运行所有模块测试"""
        self.log("=" * 60)
        self.log("🚀 开始系统模块功能检测")
        self.log("=" * 60)
        
        start_time = time.time()
        
        # 按顺序测试各个模块
        modules = [
            ("temperature", self.test_temperature_module),
            ("vibration", self.test_vibration_module), 
            ("audio", self.test_audio_module),
            ("camera", self.test_camera_module)
        ]
        
        for module_name, test_func in modules:
            self.log(f"\n📍 正在测试: {module_name}")
            try:
                test_func()
            except Exception as e:
                self.log(f"❌ 模块 {module_name} 测试异常: {e}")
                
        total_time = time.time() - start_time
        
        # 生成测试报告
        self.log("\n" + "=" * 60)
        self.log("📋 模块检测结果报告")
        self.log("=" * 60)
        
        passed_count = 0
        failed_count = 0
        
        for module_name, result in self.test_results.items():
            status_icon = "✅" if result.status == "passed" else "❌"
            self.log(f"{status_icon} {result.module_name}: {result.status.upper()}")
            self.log(f"   └─ {result.message}")
            self.log(f"   └─ 测试耗时: {result.test_duration:.2f}秒")
            
            if result.status == "passed":
                passed_count += 1
            else:
                failed_count += 1
        
        self.log("-" * 60)
        self.log(f"📊 总计: {passed_count}个模块正常, {failed_count}个模块异常")
        self.log(f"⏱️  总测试时间: {total_time:.2f}秒")
        self.log("=" * 60)
        
        return self.test_results
    
    def get_test_summary(self):
        """获取测试摘要"""
        if not self.test_results:
            return {"status": "not_tested", "message": "未进行测试"}
            
        passed = sum(1 for r in self.test_results.values() if r.status == "passed")
        total = len(self.test_results)
        
        if passed == total:
            status = "all_passed"
            message = f"所有{total}个模块测试通过"
        elif passed > 0:
            status = "partial_passed" 
            message = f"{passed}/{total}个模块测试通过"
        else:
            status = "all_failed"
            message = f"所有{total}个模块测试失败"
            
        return {
            "status": status,
            "message": message,
            "passed": passed,
            "total": total,
            "details": {name: {
                "status": result.status,
                "message": result.message,
                "duration": result.test_duration
            } for name, result in self.test_results.items()}
        }

# 导入现有模块
from temp_GY906 import read_temp

from photo import PhotoCapture

# 其他类保持不变...
class WebDataBuffer:
    """Web数据缓冲区，用于存储实时数据"""
    def __init__(self, max_size=300):
        self.max_size = max_size
        self.temperature_data = deque(maxlen=max_size)
        self.vibration_data = deque(maxlen=max_size) 
        self.audio_data = deque(maxlen=max_size)
        self.timestamps = deque(maxlen=max_size)
        self._lock = threading.Lock()
        
        # 专门用于实时波形的高频数据缓冲区
        self.vibration_waveform = deque(maxlen=600)  # 30秒高频数据
        self.audio_waveform = deque(maxlen=600)      # 30秒高频数据
    
    def add_data(self, timestamp, temp=None, vibration=None, audio=None, is_waveform=False):
        """添加数据点"""
        with self._lock:
            # 确保时间戳格式一致
            if isinstance(timestamp, str):
                time_str = timestamp
            else:
                time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
            
            # 处理数据值，确保数值有效
            temp_val = temp if temp is not None and not np.isnan(temp) else 24.0
            vibration_val = vibration if vibration is not None and not np.isnan(vibration) else 0
            audio_val = audio if audio is not None and not np.isnan(audio) else 0.5
            
            # 添加到主数据缓冲区
            self.timestamps.append(time_str)
            self.temperature_data.append(temp_val)
            self.vibration_data.append(vibration_val)
            self.audio_data.append(audio_val)
            
            # 如果是高频波形数据，也添加到波形缓冲区
            if is_waveform:
                if vibration is not None:
                    self.vibration_waveform.append({'time': time_str, 'value': vibration_val})
                if audio is not None:
                    self.audio_waveform.append({'time': time_str, 'value': audio_val})
    
    def get_recent_data(self, count=100):
        """获取最近的数据"""
        with self._lock:
            if len(self.timestamps) == 0:
                return {"timestamps": [], "temperature": [], "vibration": [], "audio": []}
            
            recent_count = min(count, len(self.timestamps))
            return {
                "timestamps": list(self.timestamps)[-recent_count:],
                "temperature": list(self.temperature_data)[-recent_count:],
                "vibration": list(self.vibration_data)[-recent_count:],
                "audio": list(self.audio_data)[-recent_count:]
            }
    
    def get_waveform_data(self, data_type='vibration', count=100):
        """获取波形数据"""
        with self._lock:
            if data_type == 'vibration':
                data = list(self.vibration_waveform)[-count:]
            elif data_type == 'audio':
                data = list(self.audio_waveform)[-count:]
            else:
                return []
            
            return data

class SimpleAudioMonitor:
    """真实声音监控类"""
    def __init__(self):
        self.baseline_file_sizes = []
        self.baseline_durations = []
        self.is_baseline_set = False
        self.size_threshold_factor = 1.5
        self.duration_threshold_factor = 1.3
        self.logger = logging.getLogger(__name__)
    
    def detect_anomaly(self, audio_file=None):
        """真实声音异常检测"""
        if not audio_file or not os.path.exists(audio_file):
            return False, 0.0
            
        try:
            # 分析音频文件
            file_size = os.path.getsize(audio_file)
            
            # 使用wave模块分析音频
            with wave.open(audio_file, 'rb') as wav_file:
                frames = wav_file.getnframes()
                sample_rate = wav_file.getframerate()
                duration = frames / float(sample_rate)
            
            # 如果还没有建立基线，建立基线
            if not self.is_baseline_set:
                self.baseline_file_sizes.append(file_size)
                self.baseline_durations.append(duration)
                
                if len(self.baseline_file_sizes) >= 10:
                    self.is_baseline_set = True
                    self.logger.info("音频基线已建立")
                
                return False, 0.3  # 建立基线期间返回正常
            
            # 计算异常分数
            avg_size = np.mean(self.baseline_file_sizes)
            avg_duration = np.mean(self.baseline_durations)
            
            size_ratio = file_size / avg_size if avg_size > 0 else 1.0
            duration_ratio = duration / avg_duration if avg_duration > 0 else 1.0
            
            # 综合异常分数
            anomaly_score = max(
                abs(size_ratio - 1.0),
                abs(duration_ratio - 1.0)
            )
            
            is_anomaly = anomaly_score > 0.5
            
            return is_anomaly, min(anomaly_score, 1.0)
            
        except Exception as e:
            self.logger.error(f"音频异常检测错误: {e}")
            return False, 0.0

class WebBearingMonitor:
    def __init__(self, test_name="", operator="", bearing_model="", run_startup_tests=True):
        self.test_name = test_name or f"test_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
        self.operator = operator
        self.bearing_model = bearing_model
        self.running = False
        
        # 数据存储
        self.data_dir = f"test_data/{self.test_name}"
        self._create_directories()
        
        # 传感器实例
        self.photo_capture = PhotoCapture(output_dir=f"{self.data_dir}/photos")
        self.audio_detector = SimpleAudioMonitor()
        
        # Web数据缓冲区
        self.web_buffer = WebDataBuffer()
        
        # 数据队列
        self.temp_queue = Queue()
        self.vibration_queue = Queue()
        self.audio_queue = Queue()
        
        # 监控参数
        self.temp_threshold = 80.0
        self.vibration_threshold = 2.0
        self.monitoring_interval = 1.0
        
        # 拍照策略参数
        self.photo_interval_normal = 300
        self.photo_interval_anomaly = 60
        self.last_photo_time = 0
        self.continuous_anomaly_start = None
        self.baseline_photo_taken = False
        
        # 温度传感器校准
        self.temp_calibration_offset = 0.0
        self.temp_sensor_verified = True
        
        # 异常检测
        self.anomaly_log = []
        self.current_anomalies = set()
        
        # 模块测试器
        self.module_tester = SystemModuleTester()
        self.startup_test_results = {}
        
        # Web应用初始化
        self.app = Flask(__name__)
        self.app.config['SECRET_KEY'] = 'bearing_monitor_secret_key'
        self.socketio = SocketIO(self.app, cors_allowed_origins="*")
        
        # 设置日志
        self._setup_logging()
        self.module_tester.set_logger(self.logger)
        
        # 数据文件
        self.setup_data_files()
        
        # 启动时模块检测
        if run_startup_tests:
            self.startup_test_results = self.module_tester.run_all_tests()
        
        # 设置Web路由
        self._setup_web_routes()
        
    def _create_directories(self):
        """创建必要的目录结构"""
        dirs = [
            self.data_dir,
            f"{self.data_dir}/photos",
            f"{self.data_dir}/recordings", 
            f"{self.data_dir}/reports",
            f"{self.data_dir}/logs",
            f"{self.data_dir}/audio_training"
        ]
        for dir_path in dirs:
            os.makedirs(dir_path, exist_ok=True)
            
    def _setup_logging(self):
        """设置日志系统"""
        log_file = f"{self.data_dir}/logs/monitor.log"
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler(log_file),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    
    def setup_data_files(self):
        """初始化数据文件"""
        self.monitor_file = f"{self.data_dir}/monitoring_data.csv"
        with open(self.monitor_file, 'w', newline='') as f:
            writer = csv.writer(f)
            writer.writerow([
                'timestamp', 'temperature_c', 'temp_calibrated', 'vibration_x', 'vibration_y', 'vibration_z',
                'gyro_x', 'gyro_y', 'gyro_z', 'angle_x', 'angle_y', 'angle_z',
                'audio_anomaly', 'audio_score', 'anomaly_detected', 'anomaly_type', 'photo_taken', 'notes'
            ])
            
        self.anomaly_file = f"{self.data_dir}/anomaly_events.csv"
        with open(self.anomaly_file, 'w', newline='') as f:
            writer = csv.writer(f)
            writer.writerow([
                'timestamp', 'event_type', 'severity', 'description', 
                'temp_value', 'vibration_value', 'audio_score', 'action_taken'
            ])
    
    def _setup_web_routes(self):
        """设置Web路由"""
        
        @self.app.route('/')
        def index():
            """主页面"""
            return render_template('monitor_with_tests.html', 
                                 test_name=self.test_name,
                                 operator=self.operator,
                                 bearing_model=self.bearing_model)
        
        @self.app.route('/api/status')
        def get_status():
            """获取系统状态"""
            return jsonify({
                'running': self.running,
                'test_name': self.test_name,
                'operator': self.operator,
                'bearing_model': self.bearing_model,
                'temp_sensor_verified': self.temp_sensor_verified,
                'audio_baseline_set': self.audio_detector.is_baseline_set,
                'anomaly_count': len(self.anomaly_log),
                'photos_taken': len([f for f in os.listdir(f"{self.data_dir}/photos") 
                                   if f.endswith('.jpg')]) if os.path.exists(f"{self.data_dir}/photos") else 0,
                'startup_tests': self.module_tester.get_test_summary()
            })
        
        @self.app.route('/api/test_results')
        def get_test_results():
            """获取启动测试结果"""
            return jsonify(self.module_tester.get_test_summary())
        
        @self.app.route('/api/data')
        def get_data():
            """获取实时数据"""
            count = request.args.get('count', 100, type=int)
            return jsonify(self.web_buffer.get_recent_data(count))
        
        @self.app.route('/api/take_photo', methods=['POST'])
        def take_photo():
            """远程拍照"""
            try:
                success = self.photo_capture.capture_photo()
                if success:
                    return jsonify({'success': True, 'message': '拍照成功'})
                else:
                    return jsonify({'success': False, 'message': '拍照失败'})
            except Exception as e:
                return jsonify({'success': False, 'message': f'拍照错误: {str(e)}'})
        
        @self.app.route('/api/photos')
        def get_photos():
            """获取照片列表"""
            try:
                photos_dir = f"{self.data_dir}/photos"
                if not os.path.exists(photos_dir):
                    return jsonify([])
                
                photos = []
                for filename in sorted(os.listdir(photos_dir), reverse=True)[:12]:
                    if filename.endswith('.jpg'):
                        filepath = os.path.join(photos_dir, filename)
                        file_stat = os.stat(filepath)
                        
                        timestamp = datetime.fromtimestamp(file_stat.st_mtime).strftime('%Y-%m-%d-%H-%M-%S')
                        
                        photos.append({
                            'filename': filename,
                            'timestamp': timestamp,
                            'path': f'/photos/{filename}',
                            'created': datetime.fromtimestamp(file_stat.st_mtime).strftime('%Y-%m-%d %H:%M:%S')
                        })
                
                return jsonify(photos)
            except Exception as e:
                self.logger.error(f"获取照片列表错误: {e}")
                return jsonify([])
        
        @self.app.route('/photos/<filename>')
        def get_photo(filename):
            """获取照片文件"""
            return send_from_directory(f"{self.data_dir}/photos", filename)
        
        @self.app.route('/api/anomalies')
        def get_anomalies():
            """获取异常记录"""
            recent_anomalies = self.anomaly_log[-20:] if len(self.anomaly_log) > 20 else self.anomaly_log
            return jsonify(recent_anomalies)
        
        # WebSocket事件
        @self.socketio.on('connect')
        def handle_connect():
            """客户端连接"""
            emit('status', {'message': '连接成功'})
            # 发送启动测试结果
            emit('startup_tests', self.module_tester.get_test_summary())
        
        @self.socketio.on('disconnect')
        def handle_disconnect():
            """客户端断开连接"""
            pass
    
    def temperature_monitor(self):
        """温度监控线程"""
        self.logger.info("启动温度监控线程")
        
        while self.running:
            try:
                temp_raw = read_temp()
                temp_calibrated = temp_raw + self.temp_calibration_offset
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
                
                self.temp_queue.put({
                    'timestamp': timestamp, 
                    'temperature_raw': temp_raw,
                    'temperature': temp_calibrated,
                    'verified': self.temp_sensor_verified
                })
                
                # 添加到Web缓冲区
                self.web_buffer.add_data(timestamp, temp=temp_calibrated)
                
                # 通过WebSocket发送实时数据
                self.socketio.emit('temperature_data', {
                    'timestamp': timestamp,
                    'temperature': temp_calibrated,
                    'raw': temp_raw
                })
                
                if temp_calibrated > self.temp_threshold:
                    self._log_anomaly('temperature', 'high', 
                                    f"轴承温度过高: {temp_calibrated:.2f}°C", 
                                    temp_calibrated, 0, 0)
                    
                time.sleep(1.0)
                
            except Exception as e:
                self.logger.error(f"温度读取错误: {e}")
                time.sleep(1)
    
    def vibration_monitor(self):
        """振动监控线程 - 使用真实IMU数据"""
        self.logger.info("启动振动监控线程")
        
        # 启动IMU进程
        imu_process = None
        try:
            self.logger.info("启动IMU数据采集进程...")
            imu_process = subprocess.Popen(
                [sys.executable, "imu_node.py", "26:EF:60:96:87:3A"],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=os.getcwd()
            )
            
            # 等待IMU进程启动
            time.sleep(2)
            
            if imu_process.poll() is not None:
                self.logger.error("IMU进程启动失败")
                return
                
        except Exception as e:
            self.logger.error(f"无法启动IMU进程: {e}")
            return
        
        while self.running:
            try:
                # 这里应该从IMU进程读取真实数据
                # 实际实现需要建立进程间通信
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
                
                # 暂时跳过，等待真实IMU数据实现
                if imu_process and imu_process.poll() is None:
                    # IMU进程正常运行
                    pass
                else:
                    self.logger.error("IMU进程异常退出")
                    break
                
                time.sleep(0.1)
                
            except Exception as e:
                self.logger.error(f"振动数据读取错误: {e}")
                time.sleep(1)
        
        # 清理IMU进程
        if imu_process and imu_process.poll() is None:
            imu_process.terminate()
            imu_process.wait(timeout=2)
    
    def audio_monitor(self):
        """音频监控线程 - 使用真实录音数据"""
        self.logger.info("启动音频监控线程")
        
        # 启动录音进程
        rec_process = None
        try:
            self.logger.info("启动录音数据采集进程...")
            rec_process = subprocess.Popen(
                [sys.executable, "rec.py"],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=os.getcwd()
            )
            
            time.sleep(1)
            
            if rec_process.poll() is not None:
                self.logger.error("录音进程启动失败")
                return
                
        except Exception as e:
            self.logger.error(f"无法启动录音进程: {e}")
            return
        
        while self.running:
            try:
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
                
                # 检查录音文件
                recordings_dir = "recordings"
                if os.path.exists(recordings_dir):
                    audio_files = [f for f in os.listdir(recordings_dir) if f.endswith('.wav')]
                    if audio_files:
                        latest_file = os.path.join(recordings_dir, sorted(audio_files)[-1])
                        
                        # 使用真实的声音异常检测
                        is_anomaly, anomaly_score = self.audio_detector.detect_anomaly(latest_file)
                        
                        self.audio_queue.put({
                            'timestamp': timestamp,
                            'filename': os.path.basename(latest_file),
                            'is_anomaly': is_anomaly,
                            'anomaly_score': anomaly_score
                        })
                        
                        # 添加到Web缓冲区
                        self.web_buffer.add_data(timestamp, audio=anomaly_score, is_waveform=True)
                        
                        # 通过WebSocket发送实时数据
                        self.socketio.emit('audio_data', {
                            'timestamp': timestamp,
                            'filename': os.path.basename(latest_file),
                            'is_anomaly': is_anomaly,
                            'score': anomaly_score
                        })
                        
                        if is_anomaly:
                            self._log_anomaly('audio', 'medium',
                                            f"声音异常检测: 分数={anomaly_score:.3f}", 
                                            0, 0, anomaly_score)
                
                time.sleep(2.0)  # 每2秒检查一次录音文件
                
            except Exception as e:
                self.logger.error(f"音频监控错误: {e}")
                time.sleep(1)
        
        # 清理录音进程
        if rec_process and rec_process.poll() is None:
            rec_process.terminate()
            rec_process.wait(timeout=2)
    
    def _log_anomaly(self, event_type, severity, description, temp_val, vibr_val, audio_score):
        """记录异常事件"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        anomaly = {
            'timestamp': timestamp,
            'type': event_type,
            'severity': severity,
            'description': description,
            'temperature': temp_val,
            'vibration': vibr_val,
            'audio_score': audio_score
        }
        
        self.anomaly_log.append(anomaly)
        
        # 通过WebSocket发送异常通知
        self.socketio.emit('anomaly_alert', anomaly)
        
        self.logger.warning(f"异常检测: {description}")
    
    def main_monitor(self):
        """主监控循环"""
        self.logger.info("启动主监控循环")
        
        while self.running:
            try:
                time.sleep(self.monitoring_interval)
            except Exception as e:
                self.logger.error(f"主监控错误: {e}")
                time.sleep(1)
    
    def start_monitoring(self):
        """启动监控系统"""
        self.logger.info(f"开始Web版轴承测试监控 - {self.test_name}")
        
        # 显示启动测试结果摘要
        test_summary = self.module_tester.get_test_summary()
        self.logger.info(f"启动检测结果: {test_summary['message']}")
        
        self.running = True
        
        # 启动监控线程
        threads = [
            threading.Thread(target=self.temperature_monitor, daemon=True),
            threading.Thread(target=self.vibration_monitor, daemon=True),
            threading.Thread(target=self.audio_monitor, daemon=True),
            threading.Thread(target=self.main_monitor, daemon=True)
        ]
        
        for thread in threads:
            thread.start()
        
        # 启动Web服务器
        self.logger.info("启动Web服务器，访问地址: http://192.168.1.5:5006")
        self.socketio.run(self.app, host='0.0.0.0', port=5006, debug=False, allow_unsafe_werkzeug=True)
    
    def stop_monitoring(self):
        """停止监控"""
        self.logger.info("停止监控系统")
        self.running = False

def main():
    print("=== Web版改进轴承性能测试监控系统 - 启动检测版 ===")
    print("功能特性：")
    print("1. 启动时模块功能检测")
    print("2. 温度传感器实时监控")
    print("3. 真实振动数据监控")  
    print("4. 真实声音监控系统")
    print("5. Web实时监控界面")
    print("6. 实时波形图显示")
    print("7. 远程拍照功能")
    print()
    
    # 自动配置启动
    monitor = WebBearingMonitor("production_test", "operator", "bearing_201", run_startup_tests=True)
    
    # 设置信号处理
    def signal_handler(sig, frame):
        print("\n正在停止监控...")
        monitor.stop_monitoring()
        sys.exit(0)
        
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)
    
    try:
        monitor.start_monitoring()
    except Exception as e:
        print(f"监控系统启动失败: {e}")
        return 1
        
    return 0

if __name__ == "__main__":
    sys.exit(main())